package com.pro.springboot.interfacep;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;


public abstract class MultiThreadiInteface<T> {
    protected BlockingQueue<T> linkedQueue = new LinkedBlockingQueue<T>(1);
    protected List<Thread> threadList = new ArrayList<Thread>();

    /**
     * @Description:判断分线程是否执行完毕
     * @return
     * @author: 玄承勇
     * @date: 2017年2月7日 上午8:42:02
     */
    protected boolean finish4Thread() {
        if (isEmpty4queue()) {
            if (executed()) {
                return true;
            }
        }
        return false;

    }

    private boolean executed() {
        int loop_num = 0;
        while (true) {
            if (loop_num < 3) {
                if (isWaiting()) {
                    loop_num++;
                   // log.warn("第" + loop_num + "次所有线程处于等待状态。5分钟后再次访问");
                    try {
                        TimeUnit.SECONDS.sleep(10);
                    } catch (InterruptedException e) {
//                        log.error(e.getMessage(), e);
                    }
                } else {
//                    log.info("当前分线程还未执行完。1分钟后再次访问");
                    loop_num = 0;
                    try {
                        TimeUnit.SECONDS.sleep(10);
                    } catch (InterruptedException e) {
//                        log.error(e.getMessage(), e);
                    }
                }

            } else {
//                log.info("连续三次所有线程处于等待状态。线程执行完毕。");
                return true;
            }
        }
    }

    private boolean isEmpty4queue() {
        int loop_num = 0;
        while (true) {
            if (loop_num < 10) {
                if (linkedQueue.size() == 0) {
                    loop_num++;
//                    log.warn("第" + loop_num + "次队列数目为空。10秒钟后再次访问。");
                    try {
                        TimeUnit.SECONDS.sleep(10);
                    } catch (InterruptedException e) {
//                        log.error(e.getMessage(), e);
                    }
                } else {
//                    log.info("当前队列不为空。一分钟后再次访问");
                    loop_num = 0;
                    try {
                        TimeUnit.SECONDS.sleep(10);
                    } catch (InterruptedException e) {
//                        log.error(e.getMessage(), e);
                    }
                }

            } else {
//                log.info("连续十次阻塞队列为空。已无可用数据推送到阻塞队列中");
                return true;
            }
        }
    }

    private boolean isWaiting() {
        for (Thread each : threadList) {
            if (!each.getState().toString().equals("WAITING")) {
                return false;
            }
        }
        return true;
    }

    /**
     * 初始化多线程。
     * 
     * @param threadNum
     * @author 玄承勇
     * @date 2014-9-9 上午11:43:50
     */
    protected void initMultiThread(int threadNum) {
        if (threadNum < 0) {
//            log.error("开启线程是数量不能小于0");
            System.exit(0);
        }

        for (int i = 0; i < threadNum; i++) {
            threadList.add(new Thread() {
                public void run() {
                    while (true) {
                        customer();
                    }
                }
            });
        }
        threadList.forEach(e -> e.start());
    }

    protected boolean isEmpty(String str) {
        return str == null || "".equals(str.trim());
    }

    /**
     * 抽象方法。子类根据具体情况实现
     *
     * @author 玄承勇
     * @date 2014-9-9 上午11:44:02
     */
    public abstract void customer();

    /**
     * 抽象方法。用于恢复线程打断
     * 
     * @author 玄承勇
     * @date 2014-9-13 上午9:45:06
     */
    public abstract void recovery();

}
